﻿using System.Collections.Generic;
using Xunit;
using YAPL.Language.Ast;

namespace YAPL.Test.YAPL.Language.Ast {

	public class CodeBlockExpressionTest {
		[Fact]
		public void NodeEqualsShouldWorkCorrectly() {
			var exprList1 = new List<Expression>();
			var exprList2 = new List<Expression>();
			var exprList3 = new List<Expression>();

			exprList1.Add(Expressions.Assignment(Expressions.Variable("a"), Expressions.StringLiteral("hello1")));
			exprList1.Add(Expressions.ReturnStatement(Expressions.Variable("a")));


			exprList2.Add(Expressions.ReturnStatement(Expressions.StringLiteral("hello2")));

			exprList3.Add(Expressions.Assignment(Expressions.Variable("a"), Expressions.StringLiteral("hello1")));
			exprList3.Add(Expressions.ReturnStatement(Expressions.StringLiteral("hello2")));

			var codeblock1 = Expressions.CodeBlock(exprList1);
			var codeblock2 = Expressions.CodeBlock(exprList2);
			var codeblock3 = Expressions.CodeBlock(exprList3);

			Assert.False(codeblock1.NodeEquals(null));
			Assert.False(codeblock1.NodeEquals(Expressions.Variable("a")));
			Assert.False(codeblock1.NodeEquals(codeblock2));
			Assert.True(codeblock1.NodeEquals(codeblock3));
		}

		[Fact]
		public void RewriteChildSHouldWorkCorrectly() {
			var a = Expressions.Variable("a");
			var b = Expressions.Variable("b");
			var codeBlock = Expressions.CodeBlock(new List<Expression> {a, b});
			var r1 = codeBlock.RewriteChild(a, Expressions.Integer(1));
			var r2 = codeBlock.RewriteChild(b, Expressions.Variable("c"));

			Assert.True(r1);
			Assert.True(r2);

			Assert.IsType(typeof(ConstantExpression), codeBlock.Expressions[0]);
			var i1 = (ConstantExpression)codeBlock.Expressions[0];
			Assert.Equal(1, (int)i1.Value);

			Assert.IsType(typeof(VariableExpression), codeBlock.Expressions[1]);
			var c = (VariableExpression)codeBlock.Expressions[1];
			Assert.Equal("c", c.Name);
		}
	}
}
